// 实现这个项目的构建任务

/** 
 * 需要完成的任务
 * 1、针对scss的样式编译
 * 2、针对js的编译
 * 3、针对页面模板的编译 
 * 4、针对图片及字体文件的转化
 * 5、其他文件的清除复制
 * 6、热更新
 * 7、监视代码变化更新
 * 8、代码内的引用处理以及代码压缩
 * 9、代码格式化检查
 * 10、自动部署打包文件
*/

const { src, dest, parallel, series, watch } = require('gulp')
const del = require('del')
const browserSync = require('browser-sync')
const loadPlugins = require('gulp-load-plugins')
const plugins = loadPlugins()
const browser = browserSync.create()

const data = {
    pkg: require('./package.json'),
    date: new Date()
}
// 定义eslint规则
const eslintRules = {
    rules: {
        'my-custom-rule': 1,
        'strict': 2
    },
    globals: [
        'jQuery',
        '$'
    ],
    envs: [
        'browser'
    ]
}

// 定义清除任务
const clean = () => {
    return del('dist', 'temp')
}

// 定义style编译转化任务
const style = () => {
    return src('src/assets/styles/*.scss', { base: 'src' })
        .pipe(plugins.sass({ outputStyle: 'expanded' })) // 命名有下划线的文件不会被转化， 会被认为是项目依赖文件
        .pipe(dest('temp'))
        .pipe(browser.reload({ stream: true }))
}

// 定义js编译转化任务
const script = () => {
    return src('src/assets/scripts/*.js', { base: 'src' })
        .pipe(plugins.babel({ presets: ['@babel/preset-env'] })) // @babel/preset-env 必须要配置，不然不会转化编译
        .pipe(dest('temp'))
        .pipe(browser.reload({ stream: true }))
}

// 定义页面转化
const page = () => {
    return src('src/*.html', { base: 'src' })
        .pipe(plugins.swig({ data }))
        .pipe(dest('temp'))
        .pipe(browser.reload({ stream: true }))
}

// 定义转化压缩image
const image = () => {
    return src('src/assets/images/**', { base: 'src' })
        .pipe(plugins.imagemin())
        .pipe(dest('dist'))
}

// 定义转化压缩字体
const font = () => {
    return src('src/assets/fonts/**', { base: 'src' })
        .pipe(plugins.imagemin())
        .pipe(dest('dist'))
}

// 其他文件复制
const extra = () => {
    return src('public/**', { base: 'public' })
        .pipe(dest('dist'))
}

// 监控代码 自动执行编译运行
const serve = () => {
    watch('src/assets/styles/*.scss', style)
    watch('src/assets/scripts/*.js', script)
    watch('src/*.html', page)
    watch([
        'src/assets/images/**',
        'src/assets/fonts/**',
        'public/**'
    ], browser.reload)

    browser.init({
        notify: false,
        port: 2080,
        open: false, // 是否自动打开浏览器
        server: {
            baseDir: ['temp', 'src', 'public'],
            routes: {
                '/node_modules': 'node_modules'
            }
        }
    })

}

// 定义格式化
const lint = () => {
    return src(['**/*.js', '!node_modules/**'])
        .pipe(plugins.eslint(eslintRules))
        .pipe(plugins.eslint.formatEach('compact', process.stderr))
}



// 代码压缩
const useref = () => {
    return src('temp/*.html', { base: 'temp' })
        .pipe(plugins.useref({ searchPath: ['temp', '.'] }))
        // 压缩Html、Css、JavaScript
        .pipe(plugins.if(/\.js$/, plugins.uglify()))
        .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
        .pipe(plugins.if(/\.html$/, plugins.htmlmin({
            collapseWhitespace: true, // html收起标签
            minifyCss: true, // html中css处理
            minifyJS: true //html中js处理
        })))
        .pipe(dest('dist'))
}



const compile = parallel(style, script, page)

const build = series(
    clean,
    parallel(
        series(compile, useref),
        image,
        font,
        extra
    )
)

const start = series(compile, serve)


const remotePath = '/data/www/platform.envircloud.com/wisdomwc_mobile'
const config = {
    ssh: {
        host: '192.168.31.172',
        port: '8090',
        username: 'root',
        password: 'zzq123456''
    },
    remotePath,
    commands: [
        // 删除现有文件
        `rm -rf ${remotePath}`
    ]
}

const gulpSSH = new plugins.ssh({
    ignoreErrors: false,
    sshConfig: config.ssh
})

// 上传前删除现有文件,生成操作日志
const execSSH = () => {
    return gulpSSH.shell(config.commands, { filePath: 'commands.log' })
        .pipe(dest('logs'))
}

// 上传文件到服务器
const upload = () => {
    return src('./dist/**')
        .pipe(gulpSSH.dest(config.remotePath))
}

// 执行打包后 自动上传服务器
const deploy = series(build, execSSH, upload)


module.exports = {
    clean,
    serve,
    build,
    lint,
    start,
    deploy
}